when rewriting bytecode, keep in mind jumps are relative to END of opcode now
string offsets should be relative to operand position!

bytecode issues-
 operand types- basic datatypes, array/hash, variant, specific object types
                stack/local/global/pop
                requires conversion in-place
                requires conversion as-temporary
                static string
 conversion via operand is slower than conversion opcode, so use opcode when from-type is known
 linking to functions/variables within OTHER objects
 I can detect functions or code blocks that never exit without requiring the 'main' keyword.


Temporary data types-
    Special types: datatype (for as/is), 'all', 'all_other', 'nothing', 'this'
    Location: stack (temporary or variable), local, global, literal
    Type: unknown / variant
          variant hash or array
          int, str, float, obj_*
            any of these + hash or array
    obj_* subtype (applies to obj_* or strings or special values above)
    Flags: is a unique copy (not a reference to hash/array)
    for stack items, can be flagged as a direct pointer derived from an array/hash index (not w/variant type)
    String literals can be a literal or a reference into string bank
    
Operand modes- 8 bits
    0-15: base type- 0 actual entry 1 int 2 float 3 string 4 const-string 5 array 6 hash 7 obj_entity 8 obj_entity+subtype 9+ obj_* (7 types available)
    0-15 alone: literals- 0 none 1 int/offset 2 float 3 pointer (jump/c) 4 (const-)string 5-6 reserved for array/hash literals 7 'all' 8 'all_other' 9 'this'
      (this works because pop+convert-in-place+NO-convert-as-copy is illegal and conveniently 0)
    16/32: 0 pop 16 stack 32 local 48 global
    +0: convert-in-place (new hash/array ref IF converted)
    +64: do NOT convert-in-place: type is prechecked
    +128: convert-as-copy (ALWAYS a new hash/array even if proper type)
    +64+128: use with pop/stack to denote a pointer directly to the base type within an array/hash (no conversion allowed; subtype legal though)
    
    All operand modes pull a single 32bit operand out of bytecode except-
      pop or 'none/all/all_other/this'- pull nothing
      obj_entity+subtype- pulls an extra 32bit for subtype FIRST
      literal/global pointer- pulls pointer size (may be 32bit or 64bit etc)
      literal float- pulls float size (may be 32bit or more)
    
Stack entries-
    Special types: return pointer, reply pointer, reply-waiting pointer, empty, array/hash-item-pointer
    Type: int, str, float, obj_*, (specific obj_* subtype tracked by code and unneeded)
            any of these + hash or array

Globals-
    Any 'type:' above, plus subtypes are actually denoted

Array/hash members-
    Type: int, str, float, obj_*, specific obj_* subtype
    One type throughout entire structure


Single entity reference of known type, linked method/property location, known parameters- (best case)
Can be 'nothing' reference-
SEND [obj_entity] [function_ptr] [num_param]
STOREx [obj_entity] [local_ptr]
PUSHx [obj_entity] [local_ptr]

Entity reference is cast using 'as', but unsure if matches type-
OR Entity reference of unknown type, uncast, but method only exists in one script type-
Can be 'nothing' reference-
SEND [obj_entity](type) [function_ptr] [num_param]
STOREx [obj_entity](type) [local_ptr]
PUSHx [obj_entity](type) [local_ptr]

Accessing matching entities of specified type, linked method/property location, known parameters-
SEND [string|all|all_but](type) [function_ptr] [num_param]
STOREx [string|all|all_but](type) [local_ptr]
PUSHx [string|all|all_but](type) [local_ptr]

Entity reference of unknown type, uncast, cannot know location of method or property-
Can be 'nothing' reference-
SEND [obj_entity] [string] [num_param]
STOREx [obj_entity] [string]
PUSHx [obj_entity] [string]

Accessing matching entities of unknown/any type, cannot know location of method or property-
SEND [string|all|all_but] [string] [num_param]
STOREx [string|all|all_but] [string]
PUSHx [string|all|all_but] [string]


FURTHER TODO: (need to reevaluate in light of recent changes)

whenever requesting a token, you can say "not looking for a newline" and it'll ignore them?

shorthand to access all objects of a given name-
with (ball)
{
  x = other.x;
  y = other.y;
}

also of note- 'other'- need a way to refer to the 'sending' object if there is one

use variables for common things like x/y position?
built-in variables/variables that trigger get/set events?

How to peek beyond current block for possibly main/possibly replies?
 
void return type to avoid 'did not return a value' error?

global (and local!) initialization needs clarification/strategy

condense [offset] (S) (B) etc into one [Raw] addr mode
[reuse] addr mode?

array constants (as a var/datatype)

finish const assignment
finish string virtualization in const vars
certain other built-ins may become operators or pseudo-operators (self, values, changename, indices, length, substr, sizeof)

add internal operand modes- 'datatype', '(something) as script name'

&&||^^real as alternate syntax
